#include "toast.h"
#include "datautils.h"
#include "weatherforecast.h"
#include "ui_weatherforecast.h"

#include <QDebug>
#include <QMouseEvent>
#include <QVBoxLayout>
#include <QPluginLoader>

WeatherForecast::WeatherForecast(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::WeatherForecast)
    , m_menu(new SlideMenu(this)) // 初始化菜单
{
    ui->setupUi(this);

    /*初始化最小系统托盘*/
    // 设置程序图标
    setWindowIcon(QIcon(":/icon/images/weatherForecast.ico"));

    // 初始化托盘处理器
    trayHandler = new SystemTray(this);
    trayHandler->setupTrayIcon(this);
    // 连接信号和槽处理托盘事件
    connect(trayHandler, &SystemTray::restoreHandler, this, [this](){
        showNormal();
        activateWindow();
    });
    connect(trayHandler, &SystemTray::quitHandler, qApp, &QApplication::quit);

    /*初始化城市列表*/
    // 初始化城市菜单
    m_menu->hide();
    m_menu->setFixedWidth(width() * 0.35);
    m_menu->setFixedHeight(height());
    m_menu->move(-m_menu->width(), 0);

    // 配置动画
    m_menuAnimation.setTargetObject(m_menu);
    m_menuAnimation.setPropertyName("pos");
    m_menuAnimation.setDuration(300);
    m_menuAnimation.setEasingCurve(QEasingCurve::OutQuad);
    // 事件过滤
    installEventFilter(this);
    // 信号连接
    connect(m_menu, &SlideMenu::citySelected, this, &WeatherForecast::handleCitySelect);
    connect(ui->cityBt, &QPushButton::clicked, [this]{
        toggleMenu(!m_menuExpanded); // 使用状态变量控制
    });

    /*初始化插件指针获取*/
    loadPlugins();

    /*初始化天气信息获取*/
    dataParse = new DataParse(this);
    // 连接天气数据获取和处理槽函数
    connect(dataParse, &DataParse::FutureInfoReady, this, &WeatherForecast::handleFutureData);
    connect(dataParse, &DataParse::CurrentInfoReady, this, &WeatherForecast::handleCurrentData);
    connect(dataParse, &DataParse::errorOccurred, this, &WeatherForecast::onError);

    /*搜索和回车搜索功能*/
    connect(ui->searchBt, &QPushButton::clicked, this, [this]() {
        QString input = ui->searchEdit->text().trimmed();
        QString city = CityConverter::toPinyin(input);
        if (!city.isEmpty()) {
            dataParse->getWeatherInfo(city);
            ui->searchEdit->clear();
        } else {
            Toast::show(this, "无效城市输入", 1000);
        }
    });
    connect(ui->searchEdit, &QLineEdit::returnPressed, this, [this]() {
        ui->searchBt->click();  // 模拟按钮点击
        ui->searchEdit->clear();
    });

    /*刷新按钮功能*/
    connect(ui->flushedBt, &QPushButton::clicked, this ,&WeatherForecast::flushedInfo);

    // 默认加载一次深圳
    dataParse->getWeatherInfo(defaultCity);

    // 初始化主窗口属性
    setWindowTitle("天气预报");
    resize(800, 450);  // 默认尺寸800x450
}

WeatherForecast::~WeatherForecast()
{
    delete ui;
    // 删除指针释放内存
    delete m_Datas;
    delete m_Draw;
    delete m_Info;
    delete m_Complex;
}

void WeatherForecast::handleFutureData(const QVector<FutureDays> &futuredays) {
    qDebug() << "获取到有效七天数据";
    m_Future = futuredays;

    if (!m_Future.isEmpty()) {
        hasFuture = true;
    } else {
        // dataParse->getWeatherInfo(defaultCity);
        return ;
    }
    if (hasFuture) {
        hasFuture = false; // 重新验证数据有效性
    }
}

void WeatherForecast::handleCurrentData(const CurrentDay &currentday) {
    qDebug() << "获取到有效当日数据";
    m_Current = currentday;

    if (!m_Current.city.isEmpty()) {
        hasCurrent = true;
    } else {
        // dataParse->getWeatherInfo(defaultCity);
        return ;
    }

    if(hasCurrent) {
        // 更新界面信息
        updateWeatherUI();
        hasCurrent = false; // 重新验证数据有效性
    }
}

void WeatherForecast::onError(const QString& error) {
    qWarning() << QString("错误: %1").arg(error);
    Toast::show(this, "无效城市输入", 1000);
}

// 加载插件指针
void WeatherForecast::loadPlugins() {
    // 加载日期插件
    QPluginLoader multiDatas(QCoreApplication::applicationDirPath() + "/../multidatas/multidatas.dll");
    m_Datas = qobject_cast<MultiDatasInterface*>(multiDatas.instance());
    if (!m_Datas) {
        qWarning() << "复合数据插件加载失败:" << multiDatas.errorString();
        return ;
    }

    // 加载温度曲线插件
    QPluginLoader tempDraw(QCoreApplication::applicationDirPath() + "/../tempdraw/tempdraw.dll");
    m_Draw = qobject_cast<TempDrawInterface*>(tempDraw.instance());
    if (!m_Draw) {
        qWarning() << "温度绘图插件加载失败:" << tempDraw.errorString();
        return ;
    }

    // 加载天气信息插件
    QPluginLoader dayInfo(QCoreApplication::applicationDirPath() + "/../dayinfo/dayinfo.dll");
    m_Info = qobject_cast<DayInfoInterface*>(dayInfo.instance());
    if (!m_Info) {
        qWarning() << "当日天气插件加载失败:" << dayInfo.errorString();
        return;
    }

    // 加载详细信息插件
    QPluginLoader complex(QCoreApplication::applicationDirPath() + "/../complex/complex.dll");
    m_Complex = qobject_cast<ComplexInterface*>(complex.instance());
    if (!m_Complex) {
        qWarning() << "当日详细信息插件加载失败:" << complex.errorString();
        return;
    }
}

// 更新天气UI
void WeatherForecast::updateWeatherUI() {
    // 验证数据
    if (m_Future.isEmpty()) {
        qWarning() << "updateWeatherUI()的天气数据未就绪，重新加载";
        dataParse->getWeatherInfo(defaultCity);
        return ;
    }

    qDebug() << "开始更新主界面";

    // 更新UI日期
    ui->dateLb->setText(QString("%1  %2").arg(m_Future.first().date, m_Future.first().week));

    /*管理未来天气信息UI*/
    // 加载数据
    QStringList dates;
    QStringList weeks;
    QStringList weatherTypes;
    QStringList windTypes;
    QStringList windLevels;
    QStringList icons;
    QVector<double> tempHights;
    QVector<double> tempLows;

    // 加载未来7天数据
    for (int i = 0; i < 7 && i < m_Future.size(); ++i) {
        const FutureDays &day = m_Future[i];

        if (!m_Future.isEmpty()) {
            hasFuture = true;
        } else {
            dataParse->getWeatherInfo(defaultCity);
            return ;
        }

        dates.append(day.date.mid(5).replace("-", "/"));
        weeks.append(day.week);
        weatherTypes.append(day.weatherType);
        windTypes.append(day.windDirection);
        windLevels.append(day.windPower);
        tempHights.append(day.tempHigh);
        tempLows.append(day.tempLow);
        icons.append(day.iconType);
    }

    // 清除旧布局
    clearLayout(ui->futureWidget->layout());

    // 创建新布局
    QVBoxLayout *multiLayout = new QVBoxLayout(ui->futureWidget);
    multiLayout->setSpacing(4);
    multiLayout->setContentsMargins(4, 4, 4, 4);

    QWidget *dateWidget = m_Datas->createWidget(dates, weeks);
    multiLayout->addWidget(dateWidget);

    // 插入天气信息
    QList<QPixmap> weatherIcons;
    for (int i = 0; i < icons.size(); ++i) {
        weatherIcons.append(QPixmap(icons.at(i)));
    }
    QWidget *weatherWidget = m_Datas->createIconWidget(weatherIcons, weatherTypes);
    multiLayout->addWidget(weatherWidget);

    // 添加最高温度曲线
    QWidget* tempHight = m_Draw->createWidget(tempHights);
    multiLayout->addWidget(tempHight);
    // 添加最低温度曲线
    QWidget* tempLow = m_Draw->createWidget(tempLows);
    multiLayout->addWidget(tempLow);

    // 添加风向风力
    QWidget *windWidget = m_Datas->createWidget(windTypes, windLevels);
    multiLayout->addWidget(windWidget);

    multiLayout->setStretch(0, 1);  // 日期控件占1份高度
    multiLayout->setStretch(1, 1);  // 天气图标占1份
    multiLayout->setStretch(2, 2);  // 高温曲线占2份
    multiLayout->setStretch(3, 2);  // 低温曲线占2份
    multiLayout->setStretch(4, 1);  // 风力信息占1份

    // 清空数据
    dates.clear();
    weeks.clear();
    weatherTypes.clear();
    windTypes.clear();
    windLevels.clear();
    tempHights.clear();
    tempLows.clear();
    icons.clear();

    /*管理当日天气信息UI*/
    // 加载数据
    QString temp = QString("%1").arg(m_Future.first().averageTemp);
    QString range = QString("%1~%2").arg(m_Future.first().tempLow).arg(m_Future.first().tempHigh);
    QPixmap weatherIcon(m_Future.first().iconType);

    // 清除旧布局
    clearLayout(ui->infoWidget->layout());

    QGridLayout* infoLayout = new QGridLayout(ui->infoWidget);
    infoLayout->setContentsMargins(0, 0, 0, 0);
    infoLayout->setSpacing(10);

    QWidget* weatherInfo = m_Info->createWidget(temp, m_Future.first().weatherType, range, m_Current.city, weatherIcon);
    weatherInfo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    infoLayout->addWidget(weatherInfo, 0, 0, Qt::AlignCenter);

    /*管理当日详细信息UI*/
    // 加载数据
    QString humidity = QString("%1%").arg(m_Future.first().humidity);
    QString pm25 = QString("%1").arg(m_Current.pm25);

    // 清除旧布局
    clearLayout(ui->complexWidget->layout());

    QGridLayout *comolexLayout = new QGridLayout(ui->complexWidget);
    comolexLayout->setContentsMargins(0, 0, 0, 0);
    comolexLayout->setSpacing(4);

    QWidget *complexWidget = m_Complex->createWidget(m_Future.first().windDirection,
                                                     m_Future.first().windPower,
                                                     humidity,
                                                     pm25,
                                                     m_Current.airQuality,
                                                     m_Current.lifeTips);
    complexWidget->setMinimumSize(376, 230);
    complexWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    comolexLayout->addWidget(complexWidget, 0, 0, Qt::AlignCenter);
}

// 清除布局，防止重复设置
void WeatherForecast::clearLayout(QLayout *layout) {
    if (!layout) return;
    QLayoutItem* item;
    while ((item = layout->takeAt(0))) {
        if (QWidget* widget = item->widget()) {
            widget->deleteLater();
        }
        delete item;
    }
    delete layout;
}

// 城市菜单
void WeatherForecast::toggleMenu(bool show) {
    if(m_menuAnimation.state() == QAbstractAnimation::Running) return;

    const int menuFinalX = show ? 0 : -m_menu->width();
    const int topMargin = 0; // 与顶部对齐

    m_menuAnimation.setStartValue(m_menu->pos());
    m_menuAnimation.setEndValue(QPoint(menuFinalX, topMargin));
    m_menu->raise();
    m_menu->show();

    // 连接动画完成信号
    disconnect(&m_menuAnimation, &QPropertyAnimation::finished, 0, 0);
    connect(&m_menuAnimation, &QPropertyAnimation::finished, [this, show]{
        m_menuExpanded = show; // 同步状态
        if(!show) m_menu->hide(); // 完全隐藏
    });

    m_menuAnimation.start();
}

// 城市选择处理保持可见性
void WeatherForecast::handleCitySelect(const QString &city) {
    qDebug() << "Selected city:" << city;
    dataParse->getWeatherInfo(city);
    toggleMenu(false); // 直接关闭菜单
}

// 添加事件过滤器
bool WeatherForecast::eventFilter(QObject *watched, QEvent *event)
{
    // 点击菜单外区域关闭
    if(event->type() == QEvent::MouseButtonPress && m_menuExpanded)
    {
        QMouseEvent* me = static_cast<QMouseEvent*>(event);
        if(!m_menu->geometry().contains(me->pos()))
        {
            toggleMenu(false);
            return true;
        }
    }
    return QWidget::eventFilter(watched, event);
}

// 在resizeEvent中添加
void WeatherForecast::resizeEvent(QResizeEvent* event)
{
    // 更新菜单尺寸
    m_menu->setFixedWidth(width() * 0.35);
    m_menu->setFixedHeight(height());

    if (m_lastSize != size()) {
        m_lastSize = size();
        if (m_cachedBg.isNull()) {
            m_cachedBg.load(":/icon/images/weather.jpg");
        }
        m_cachedBg = m_cachedBg.scaled(size(), Qt::KeepAspectRatioByExpanding, Qt::FastTransformation);
    }

    QWidget::resizeEvent(event);
}
void WeatherForecast::paintEvent(QPaintEvent* event) {
    QPainter p(this);
    p.drawPixmap(0, 0, m_cachedBg);
    QWidget::paintEvent(event);
}

// 重写关闭事件
void WeatherForecast::closeEvent(QCloseEvent *event) {
    if(trayHandler->isVisible()) {
        hide();
        event->ignore();
    } else {
        QWidget::closeEvent(event);
    }
}

// 刷新按钮
void WeatherForecast::flushedInfo() {
    if (m_Current.city.isEmpty()) {
        return ;
    }

    qDebug() << "刷新当前城市天气";
    QString city = CityConverter::toPinyin(m_Current.city);
    dataParse->getWeatherInfo(city);
}
